﻿using Oplaco.Samples.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web;
using System.Web.Http;
using Microsoft.WindowsAzure.Storage.Table.DataServices;
using Microsoft.WindowsAzure.Storage.Blob;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.ServiceRuntime;
using System.IO;
using Microsoft.WindowsAzure.Storage.Queue;
using Microsoft.WindowsAzure.Storage.RetryPolicies;
using System.Diagnostics;
using System.Configuration;
using Oplaco.Samples.WebApi.Providers;
using Oplaco.Samples.Repository;
using Oplaco.Samples.WebApi.Controllers.Base;

namespace Oplaco.Samples.WebApi.Controllers
{
    /// <summary>
    /// Generic file upload controller
    /// </summary>
    public class UploadController : AsyncController
    {
        #region fields
        private ArticleRepository repos;
        private CloudQueue imagesQueue;
        private static CloudBlobContainer imagesBlobContainer;
        #endregion

        /// <summary>
        /// Controller ; initializes Azure credentials, Container, Azure Database/EF
        /// </summary>
        public UploadController()
        {
            this.repos = new ArticleRepository();
            InitializeStorage();
        }

        /// <summary>
        /// Handles file uploads
        /// </summary>
        /// <returns>List of fileitems: thumbails</returns>
        [HttpPost]
        public async Task<List<FileItem>> PostMultipartStream()
        {
            List<FileItem> data = null;
            //validation
            if (!Request.Content.IsMimeMultipartContent("form-data"))
            {
                throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
            }

            try
            {
                //process file read into the stream and upload in azure
                var multipartStreamProvider = new AzureBlobStorageMultipartProvider(imagesBlobContainer);
                data = await Request.Content.ReadAsMultipartAsync<AzureBlobStorageMultipartProvider>(multipartStreamProvider).ContinueWith<List<FileItem>>(t =>
                {
                    if (t.IsFaulted)
                    {
                        throw t.Exception;
                    }
                    AzureBlobStorageMultipartProvider provider = t.Result;
                    return provider.Files;
                });

                //for test purposes, create a new article....
                Models.Article article = new Article { Title = "My latest article", LastModified = DateTime.Now, Images = data };
                await this.repos.AddArticleAsync(article);

                //-----------------------------------
                //A sample to process images without article creation
                //-----------------------------------
                //data.ForEach(async (f) => await this.repos.AddImageAsync(f));
                
                
            }
            catch (Exception ex)
            {
                Trace.TraceInformation("Something went wrong" + ex.Message);
                throw new HttpResponseException(HttpStatusCode.InternalServerError);
            }
            return data;
        }

        [HttpGet]
        //public async Task<List<FileItem>> GetArticleImages(Guid articleId)
        //{ 
        
        //}


        #region private
        private void InitializeStorage()
        {
            // Open storage account using credentials from web.config file.
            var storageAccount = CloudStorageAccount.Parse(ConfigurationManager.ConnectionStrings["StorageConnectionString"].ConnectionString);

            // Get context object for working with blobs, and 
            // set a default retry policy appropriate for a web user interface.
            var blobClient = storageAccount.CreateCloudBlobClient();
            blobClient.DefaultRequestOptions.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(3), 3);

            // Get a reference to the blob container.
            imagesBlobContainer = blobClient.GetContainerReference("images");

            // Get context object for working with queues, and 
            // set a default retry policy appropriate for a web user interface.
            CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
            queueClient.DefaultRequestOptions.RetryPolicy = new LinearRetry(TimeSpan.FromSeconds(3), 3);

            // Get a reference to the queue.
            imagesQueue = queueClient.GetQueueReference("images");
        }
        #endregion
    }
}
